<script setup lang="ts">
// 引入要用的模块
// UI组件
import { ElMessage, UploadFile, UploadInstance, UploadRawFile } from 'element-plus';
// Vue框架中需要用到
import { computed, getCurrentInstance, ComponentInternalInstance, ref, onMounted, shallowRef, onBeforeUnmount } from 'vue';
// 网络接口相关
import { CategroyResponseData, RequestPath, startRequest } from '../base/RequestWork';
// 富文本编辑器相关
import '@wangeditor/editor/dist/css/style.css';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import { IDomEditor } from '@wangeditor/editor'
// 路由模块
import { useRouter } from 'vue-router';

// 路由管理对象
let router = useRouter()
// 当前组件实例的代理对象
const { proxy }  = getCurrentInstance() as ComponentInternalInstance
// 外部属性
// mode：0表示新增 1表示编辑
// id: 新增商品时为undefined 编辑商品时为商品id
const props = defineProps(['mode', 'id'])
// 编辑的商品数据
let goods = ref({ name:"", description:"", brand:"", image:"",
    category:{ id:null }, detail:"", id: null, price:0,
    discounted_price:0, stock:0, status:0
})
// 所有类别数据，用来进行类别选择
let categoryList = ref()
// 编辑器实例
const editorRef = shallowRef();
// 过滤编辑器不需要的功能
const toolbarConfig = {
    excludeKeys: [
    'group-video',
    'fullScreen']
};
// 配置编辑器功能
const editorConfig = { 
    placeholder: '请输入内容...',
    MENU_CONF:{
        uploadImage: {
            server: 'http://localhost:3000/api/v1/common/image/upload',
            fieldName: 'file',
            customInsert(res: any, insertFn: any) {  
                insertFn(res.url, '', '')
            },
            maxFileSize: 10 * 1024 * 1024
        }
    }
};

// 编辑器创建完成的回调函数
const handleCreated = (editor:IDomEditor) => {
    editorRef.value = editor; // 记录editor实例
};

// 生命周期：组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
    const editor = editorRef.value;
    if (editor == null) return;
    editor.destroy();
});

// 生命周期：组件挂载时进行数据加载
onMounted(()=>{
    // 请求类别数据
    loadCategoryData()
    // 请求商品数据
    loadGoodsData()
}) 

// 请求类别数据的方法
function loadCategoryData() {
    // 请求所有类别数据
    startRequest(RequestPath.goodsCategoryGet, 'get', {}).then((response)=>{
        let data = response.data as CategroyResponseData
        categoryList.value = data.datas ?? []
    }).catch((error)=>{
        ElMessage.error({ message: error.response.data.error })
    })
}
// 获取商品详情数据
function loadGoodsData() {
    // 是编辑模式再进行请求
    if ((props.mode ?? 0) == 1 && props.id) {
        // 请求商品数据
        startRequest(RequestPath.goodsGet, 'get', {id: props.id}).then((response)=>{
            goods.value = response.data.datas[0];
            // 对上传图片组件的缩略图进行回显
            var blob =null;
            var xhr = new XMLHttpRequest();
            xhr.open("get", goods.value.image);
            xhr.setRequestHeader('Accept', 'image/png');
            xhr.responseType = "blob";
            xhr.onload = () => {
                blob = xhr.response;
                let imageFile = new File([blob], "", {type: 'image/png'}) as UploadRawFile;
                imageFile.uid = 0;
                //el-upload组件的添加文件方法
                (proxy?.$refs.uploadComponet as UploadInstance).handleStart(imageFile);
            };
            xhr.send();
        }).catch((error)=>{
            ElMessage.error({
                message: error.response.data.error
            })
        })
    }
}

// 计算属性，控制创建按钮的禁用状态
let disableCheak = computed(()=>{
    // 商品的数据都无为空，在允许按钮可用
    return !(goods.value.image.length > 0 && 
    goods.value.name.length > 0 && 
    goods.value.brand.length > 0 && 
    goods.value.description.length > 0 &&
    goods.value.detail.length > 0 &&
    goods.value.category.id != null)
})

// 上传成功的回调方法
function uploadImageSuccess(data:any) {
    ElMessage.success({ message: '图片添加成功' })
    goods.value.image = data.url    
}
// 上传失败的回调方法
function uploadImageError() {
    ElMessage.error({ message: '图片添加失败，请重试' })
}
// 删除了上传的文件的回调方法
const uploadImageRemove = (file: UploadFile) => {
    goods.value.image = "";
    // 手动将Upload组件显示的缩略图删掉
    (proxy?.$refs.uploadComponet as UploadInstance).handleRemove(file);
}
// 点击确认按钮执行的方法
function confirmAction() {
    // 拼装参数
    let params:any = {...goods.value}
    let path =  RequestPath.goodsUpdate
    if ((props.mode ?? 0) == 0) {
        // 如果是新建商品模式，则将参数中的id去掉
        delete params.id
        // 如果新建，将path修改为创建商品的url
        path =  RequestPath.goodsAdd
    }
    
    // 通过后端接口创建商品
    startRequest(path, 'post', params).then(()=>{
        ElMessage.success({ message: '操作成功' })
        // 跳转到商品管理模块
        router.replace({ name: 'goodsManager' })
    }).catch((error)=>{
        ElMessage.error({ message: error.response.data.error })
    })
}
</script>

<template>
    <div class="contentContainer">
        <!-- 橱窗图片上传模块 -->
        <div class="input">
            <div>橱窗图片：</div>
            <el-upload
                ref="uploadComponet"
                action="http://localhost:3000/api/v1/common/image/upload"
                method="post" name="file" list-type="picture" :limit="1"
                :on-success="uploadImageSuccess" :on-error="uploadImageError"
                style="margin-top: 20px;">
                <!-- 自定义缩略图和上传按钮的展示逻辑 -->
                <el-button type="primary" v-show="(goods.image ?? '').length == 0">选择商品橱窗图</el-button>
                <template #file="file">
                    <img class="el-upload-list__item-thumbnail" :src="goods.image ?? ''" />
                    <el-icon style="font-size: 20px; position: absolute; right: 30px;" @click="uploadImageRemove(file)"><Delete /></el-icon>
                </template>
            </el-upload>
        </div>
        <!-- 各种表单模块 -->
        <div class="input"  v-show="(props.mode ?? 0) == 1">
            <span>商品ID：</span>
            <el-input style="width: 200px;" v-model="goods.id" placeholder="请输入内容" disabled />
        </div>
        <div class="input">
            <span>商品名称：</span>
            <el-input style="width: 200px;" v-model="goods.name" placeholder="请输入内容"/>
        </div>
        <div class="input">
            <span>商品品牌：</span>
            <el-input style="width: 200px;" v-model="goods.brand" placeholder="请输入内容"/>
        </div>
        <div class="input">
            <span>商品描述：</span>
            <el-input style="width: 600px;" v-model="goods.description" placeholder="请输入内容"/>
        </div>
        <div class="input">
            <span>商品价格：</span>
            <el-input type="number" :min="0" style="width: 100px;" v-model.number="goods.price"/>
        </div>
        <div class="input">
            <span>折扣价格：</span>
            <el-input type="number" :min="0" style="width: 100px;" v-model.number="goods.discounted_price"/>
        </div>
        <div class="input">
            <span>库存数量：</span>
            <el-input type="number" :min="0" style="width: 100px;" v-model.number="goods.stock"/> 
        </div>
        <div class="input">
            <span>商品状态：</span>
            <el-select v-model="goods.status">
                <el-option :key="0" label="未上架" :value="0"/>
                <el-option :key="1" label="已上架" :value="1"/>
            </el-select>
        </div>
        <div class="input">
            <span>商品类别：</span>
            <el-select v-model="goods.category.id" placeholder="请选择商品类别">
                <el-option v-for="item in categoryList" :key="item.id" :label="item.name" :value="item.id"/>
            </el-select>
        </div>
        <div class="input">
            <div>商品详情：</div>
            <!-- 富文本编辑器部分 -->
            <div style="margin: 30px; border: gainsboro 1px solid;">
                <Toolbar :editor="editorRef" :defaultConfig="toolbarConfig" style="border-bottom: 1px solid #ccc;"/>
                <Editor :defaultConfig="editorConfig" v-model="goods.detail" style="height: 400px; overflow-y: hidden" @onCreated="handleCreated"/>
            </div>
        </div> 
        <!-- 确认按钮 -->
        <div class="input">
            <el-button type="primary" :disabled="disableCheak" @click="confirmAction">{{ (props.mode ?? 0) == 0 ? "创建商品" : "保存更改" }}</el-button>
        </div>
    </div>
</template>

<style scoped>
.input {
    margin-top: 40px;
}
</style>